/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uploadphotobucket.action;

import com.photobucket.api.core.IFileUploadProgressEventListener;
import com.photobucket.api.core.PhotobucketAPI;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.json.JSONObject;
import utils.Utils;

/**
 *
 * @author banhbaochay
 */
public class ActionPhotobucket {

    /**
     * Domain of website photobucket.com
     */
    public static final String PHOTOBUCKET_DOMAIN = "api.photobucket.com";
    /**
     * POST and GET method
     */
    public static final String POST = "POST";
    public static final String GET = "GET";
    /**
     * Predefined String for JSON to get information from JSON
     */
    public static final String SUBDOMAIN = "subdomain";
    public static final String OAUTH_TOKEN = "oauth_token";
    public static final String OAUTH_TOKEN_SECRET = "oauth_token_secret";
    public static final String USERNAME = "username";

    public ActionPhotobucket(String oauthConsumerKey, String oauthConsumerSecret) {
        this.oauthConsumerKey = oauthConsumerKey;
        this.oauthConsumerSecret = oauthConsumerSecret;
    }// end constructor

    /**
     * Ping to photobucket.com
     * @return JSONObject from string: {"timestamp":1305193807,"
     * content":{"pong":"(read)"},"status":"OK","method":"GET","format":"json"}
     * @throws Exception if error when executing ping command
     */
    public JSONObject ping() throws Exception {
        return new JSONObject(ping("json"));
    }// end ping method

    /**
     * Ping to photobucket.com
     * @param format xml, json, jsonp, phpserialize, null means xml
     * @return String from server when execute ping command
     * @throws Exception if error when executing ping command
     */
    public String ping(String format) throws Exception {
        PhotobucketAPI api = new PhotobucketAPI();
        if (format != null) {
            api.setFormat(format);
        }// end if format != null
        api.setSubdomain("api.photobucket.com");
        api.setRequestPath("/ping");
        api.setMethod("GET");
        api.setOauthConsumerKey(oauthConsumerKey);
        api.setOauthConsumerSecret(oauthConsumerSecret);
        return api.execute().getResponseString();
    }// end ping method

    /**
     * Request to photobucket.com
     * @return JSONObject contain fields: oauth_token, oauth_token_secret, next_step
     * @throws Exception 
     */
    public JSONObject request() throws Exception {
        PhotobucketAPI api = new PhotobucketAPI();
        api.setSubdomain("api.photobucket.com");
        api.setRequestPath("/login/request");
        api.setMethod("POST");
        api.setOauthConsumerKey(oauthConsumerKey);
        api.setOauthConsumerSecret(oauthConsumerSecret);
        String r = api.execute().getResponseString();
        r = r.replaceAll("=", ":").replaceAll("&", ",");
        r = "{".concat(r).concat("}");
        JSONObject json = new JSONObject(r);
        Iterator it = json.keys();
        while (it.hasNext()) {
            String k = (String) it.next();
            String v = json.getString(k);
            if (v.contains("%3A") || v.contains("%2F")) {
                v = URLDecoder.decode(v, "UTF-8");
                json.put(k, v);
            }// end if v.contains("%3A") || v.contains("%2F")
        }// end while it.hasNext()
        return json;
    }// end request method

    /**
     * Access to photobucket.com only after request
     * @param oauthToken get from request
     * @param oauthTokenSecret get from request
     * @return JSONObject contains fields: oauth_token, oauth_token_secret, username, subdomain, homeurl
     * @throws Exception
     */
    public JSONObject access(String oauthToken, String oauthTokenSecret) throws Exception {
        PhotobucketAPI api = new PhotobucketAPI();
        api.setSubdomain("api.photobucket.com");
        api.setRequestPath("/login/access");
        api.setMethod("POST");
        api.setOauthConsumerKey(oauthConsumerKey);
        api.setOauthConsumerSecret(oauthConsumerSecret);
        api.setOauthToken(oauthToken);
        api.setOauthTokenSecret(oauthTokenSecret);
        String r = api.execute().getResponseString();
        r = r.replaceAll("=", ":").replaceAll("&", ",");
        r = "{".concat(r).concat("}");
        JSONObject json = new JSONObject(r);
        /*
         * Convert String to url if has
         */
        Iterator it = json.keys();
        while (it.hasNext()) {
            String k = (String) it.next();
            String v = json.getString(k);
            if (v.contains("%3A") || v.contains("%2F")) {
                v = URLDecoder.decode(v, "UTF-8");
                json.put(k, v);
            }// end if v.contains("%3A") || v.contains("%2F")
        }// end while it.hasNext()
        return json;
    }// end access method

    /**
     * Access to photobucket.com only after request
     * @param consumerJSON get from request, consumerMap must contain oauth_token and oauth_token_secret
     * @return JSONObject contains fields: oauth_token, oauth_token_secret, username, subdomain, homeurl
     * @throws Exception 
     */
    public JSONObject access(JSONObject consumerJSON) throws Exception {
        return access(consumerJSON.getString("oauth_token"), consumerJSON.getString("oauth_token_secret"));
    }// end access method

    /**
     * Get album information of user after access to account
     * @param userJSON get from access account, userMap must contain subdomain, username, oauth_token and oauth_token_secret
     * @return JSONObject has format:<br/>
     * <ul>
     *    <li>status</li>
     *    <li>format</li>
     *    <li>method</li>
     *    <li>timestamp</li>
     *    <li>content: 
     *        <ul>
     *              <li>album: 
     *                  <ul>
     *                       <li>_attribs:
     *                            <ul>
     *                                 <li>title</li>
     *                                 <li>username</li>
     *                                 <li>subalbum_count</li>
     *                                 <li>name</li>
     *                                 <li>photo_count</li>
     *                                 <li>privacy</li>
     *                                 <li>video_count</li>
     *                                 <li>thumb</li>
     *                            </ul>
     *                       </li>
     *                       <li>media: is array, an element contains:
     *                            <ul>
     *                                 <li>_attribs:
     *                                      <ul>
     *                                           <li>name</li>
     *                                           <li>username</li>
     *                                           <li>type</li>
     *                                           <li>description_id</li>
     *                                           <li>uploaddate</li>
     *                                           <li>public</li>
     *                                      </ul>
     *                                 </li>
     *                                 <li>isSponsored</li>
     *                                 <li>title</li>
     *                                 <li>browseurl</li>
     *                                 <li>description</li>
     *                            </ul>
     *                       </li>
     *                       <li>album: is array, an element is an album</li>
     *                  </ul>
     *              </li>
     *        </ul>
     *    </li>
     * </ul>
     * @throws Exception 
     */
    public JSONObject getAlbum(JSONObject userJSON) throws Exception {
        return new JSONObject(getAlbum("json", userJSON));
    }// end getAlbum method

    /**
     * Get album information of user after access to account
     * @param format xml, json, jsonp, phpserialize, null means xml
     * @param userJSON get from access account, userMap must contain subdomain, username, oauth_token and oauth_token_secret
     * @return String from server when execute getAlbum command
     * @throws Exception 
     */
    public String getAlbum(String format, JSONObject userJSON) throws Exception {
        PhotobucketAPI api = new PhotobucketAPI();
        if (format != null) {
            api.setFormat(format);
        }// end if format != null
        api.setSubdomain(userJSON.getString(SUBDOMAIN));
        api.setRequestPath("/album/" + userJSON.getString(USERNAME));
        api.setMethod("GET");
        api.setOauthConsumerKey(oauthConsumerKey);
        api.setOauthConsumerSecret(oauthConsumerSecret);
        api.setOauthToken(userJSON.getString(OAUTH_TOKEN));
        api.setOauthTokenSecret(userJSON.getString(OAUTH_TOKEN_SECRET));
        Map<String, String> params = new HashMap<String, String>();
        params.put("recurse", "true");
        api.setParameters(params);
        return api.execute().getResponseString();
    }// end getAlbum method

    /**
     * Upload image to album name
     * @param filePath Path of file which is uploaded to album
     * @param albumName Name of album which is received image
     * @param listener An object of the class which implements IFileUploadProgressEventListener interface, display percent success
     * when uploading
     * @param userJSON get from access account, userMap must contain subdomain, username, oauth_token and oauth_token_secret
     * @return JSONObject has format: <br/>
     * <ul>
     *    <li>status</li>
     *    <li>format</li>
     *    <li>method</li>
     *    <li>timestamp</li>
     *    <li>content: 
     *        <ul>
     *              <li>browseurl</li>
     *              <li>url</li>
     *              <li>thumb</li>
     *              <li>description</li>
     *              <li>title</li>
     *        </ul>
     *    </li>
     * </ul>
     * @throws Exception 
     */
    public JSONObject uploadMedia(String filePath, String albumName,
            JSONObject userJSON, IFileUploadProgressEventListener listener) throws Exception {
        return new JSONObject(uploadMedia("json", filePath, albumName, userJSON, listener));
    }// end uploadMedia method

    /**
     * Upload image to album name
     * @param format xml, json, jsonp, phpserialize, null means xml
     * @param filePath Path of file which is uploaded to album
     * @param albumName Name of album which is received image
     * @param listener An object of the class which implements IFileUploadProgressEventListener interface, display percent success
     * when uploading
     * @param userJSON get from access account, userMap must contain subdomain, username, oauth_token and oauth_token_secret
     * @return String from server when execute upload command
     * @throws Exception 
     */
    public String uploadMedia(String format, String filePath, String albumName,
            JSONObject userJSON, IFileUploadProgressEventListener listener) throws Exception {
        String albumNameEncode;
        try {
            albumNameEncode = URLEncoder.encode(albumName, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            albumNameEncode = albumName;
        }
        File imageFile = new File(filePath);
        String fileNameWithoutExtension = Utils.getFileNameWithoutExtension(imageFile.getName());
        Map<String, String> params = new HashMap<String, String>();
        params.put("title", fileNameWithoutExtension);
        params.put("type", "image");

        PhotobucketAPI api = new PhotobucketAPI();
        if (format != null) {
            api.setFormat(format);
        }// end if format != null
        api.setSubdomain(userJSON.optString(SUBDOMAIN));
        api.setRequestPath("/album/" + albumNameEncode + "/upload");
        api.setMethod("POST");
        api.setOauthConsumerKey(oauthConsumerKey);
        api.setOauthConsumerSecret(oauthConsumerSecret);
        api.setOauthToken(userJSON.getString(OAUTH_TOKEN));
        api.setOauthTokenSecret(userJSON.getString(OAUTH_TOKEN_SECRET));
        api.setParameters(params);
        api.setUploadFile(imageFile);
        api.setUploadFileName(fileNameWithoutExtension);
        api.addFileUploadProgressEventListener(listener);

        return api.execute().getResponseString();
    }// end uploadMedia method
    private String oauthConsumerKey;
    private String oauthConsumerSecret;
}// end ActionPhotobucket class

